package com.bookstore.controller;

import com.bookstore.dto.BookDTO;
import com.bookstore.service.BookService;
import com.bookstore.service.UserHistoryService;

import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/book")
@Slf4j
public class BookController{

    @Autowired
    private BookService bookService;

    @Autowired
    private UserHistoryService userHistoryService;

    @Value("${file.upload-dir}")
    private String uploadDir;

    @GetMapping("/all")
    public ResponseEntity<?> getAllBooks(
            @RequestParam(required = false) String keyword,
            @RequestParam(required = false) String title,
            @RequestParam(required = false) String author,
            @RequestParam(required = false) String categoryId,
            @RequestParam(required = false) Double minPrice,
            @RequestParam(required = false) Double maxPrice,
            @RequestParam(required = false) String degree,
            @RequestParam(required = false) String sort,
            @RequestParam(required = false) Boolean isHot,
            @RequestParam(required = false) Boolean isRecommended,
            @RequestParam(required = false) Boolean isFlashSale,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        
        Long _categoryId = categoryId != null ? Long.parseLong(categoryId) : null;
        
        // 创建排序对象
        Sort sortObj = Sort.unsorted();
        if (sort != null) {
            switch (sort) {
                case "price-asc":
                    sortObj = Sort.by(Sort.Direction.ASC, "price");
                    break;
                case "price-desc":
                    sortObj = Sort.by(Sort.Direction.DESC, "price");
                    break;
                case "sales":
                    sortObj = Sort.by(Sort.Direction.DESC, "salesCount");
                    break;
                case "hot":
                    sortObj = Sort.by(Sort.Direction.DESC, "hotWeight");
                    break;
                case "recommended":
                    sortObj = Sort.by(Sort.Direction.DESC, "recommendWeight");
                    break;
                case "flash-sale":
                    sortObj = Sort.by(Sort.Direction.DESC, "flashSaleWeight");
                    break;
                default:
                    sortObj = Sort.by(Sort.Direction.DESC, "createTime");
                    break;
            }
        }
        
        // 处理特殊查询类型
        if (Boolean.TRUE.equals(isHot)) {
            sortObj = Sort.by(Sort.Direction.DESC, "hotWeight");
        } else if (Boolean.TRUE.equals(isRecommended)) {
            sortObj = Sort.by(Sort.Direction.DESC, "recommendWeight");
        } else if (Boolean.TRUE.equals(isFlashSale)) {
            sortObj = Sort.by(Sort.Direction.DESC, "flashSaleWeight");
        }
        
        // 创建分页对象
        Pageable pageable = PageRequest.of(page, size, sortObj);
        
        // 调用服务层方法
        Page<BookDTO> books = bookService.searchBooks(
            _categoryId,
            keyword,
            title,
            author,
            minPrice, 
            maxPrice,
            degree,
            isHot, 
            isRecommended, 
            isFlashSale, 
            pageable
        );
        return ResponseEntity.ok(books);
    }

    private String uploadImage(MultipartFile file) throws IOException {
        String contentType = file.getContentType();
        if (contentType == null || !contentType.startsWith("image/")) {
            throw new IOException("只支持图片文件上传");
        }
        String originalFilename = file.getOriginalFilename();
        String fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
        String uniqueFileName = UUID.randomUUID() + fileExtension;
        Path uploadPath = Paths.get(uploadDir);
        if (!Files.exists(uploadPath)) {
            Files.createDirectories(uploadPath);
        }
        Path filePath = uploadPath.resolve(uniqueFileName);
        Files.copy(file.getInputStream(), filePath);
        return "/uploads/" + uniqueFileName;
    }

    @PostMapping("/uploads")
    public ResponseEntity<List<String>> uploadImages(@RequestParam("files") MultipartFile[] files) {
        List<String> results = Arrays.stream(files)
                .map(file -> {
                    try {
                        return this.uploadImage(file);
                    } catch (Exception e) {
                        e.printStackTrace();
                        throw new RuntimeException("文件上传失败: " + e.getMessage());
                    }
                })
                .collect(Collectors.toList());
        return ResponseEntity.ok(results);
    }

    @GetMapping("/{id}")
    public ResponseEntity<BookDTO> getBookById(
            @PathVariable Long id,
            @RequestParam(required = false) Long userId) {
        try {
            BookDTO book = bookService.getBookById(id);

            // 如果提供了用户ID，记录浏览历史
            if (userId != null) {
                try {
                    userHistoryService.addHistory(userId, id, "VIEW");
                } catch (Exception e) {
                    // 记录历史失败不影响主流程，只记录日志
                    log.error("记录用户浏览历史失败: " + e.getMessage(), e);
                }
            }
            
            return ResponseEntity.ok(book);
        } catch (RuntimeException e) {
            return ResponseEntity.notFound().build();
        }
    }

    @PostMapping
    public ResponseEntity<?> addBook(@RequestBody BookDTO bookDTO) {
        BookDTO createdBook = bookService.createBook(bookDTO);
        return ResponseEntity.ok(createdBook);
    }

    @PostMapping("/insert")
    public ResponseEntity<?> insertBook(@RequestBody BookDTO bookDTO) {
        BookDTO createdBook = bookService.createBook(bookDTO);
        return ResponseEntity.ok(createdBook);
    }

    @DeleteMapping("/{id}")
    public ResponseEntity<?> deleteBook(@PathVariable Long id) {
        bookService.deleteBook(id);
        return ResponseEntity.ok(true);
    }

    @GetMapping("/hot")
    public ResponseEntity<List<BookDTO>> getHotBooks(
            @RequestParam(defaultValue = "10") int limit) {
        // 获取热销图书，按热度权重排序
        Sort sort = Sort.by(Sort.Direction.DESC, "hotWeight");
        Pageable pageable = PageRequest.of(0, limit, sort);
        Page<BookDTO> books = bookService.getBooksByType(true, null, null, pageable);
        return ResponseEntity.ok(books.getContent());
    }

    @GetMapping("/recommended")
    public ResponseEntity<List<BookDTO>> getRecommendedBooks(
            @RequestParam(defaultValue = "10") int limit) {
        // 获取推荐图书，按推荐权重排序
        Sort sort = Sort.by(Sort.Direction.DESC, "recommendWeight");
        Pageable pageable = PageRequest.of(0, limit, sort);
        Page<BookDTO> books = bookService.getBooksByType(null, true, null, pageable);
        return ResponseEntity.ok(books.getContent());
    }

    @GetMapping("/flash-sale")
    public ResponseEntity<List<BookDTO>> getFlashSaleBooks(
            @RequestParam(defaultValue = "10") int limit) {
        // 获取抢购图书，按抢购权重排序
        Sort sort = Sort.by(Sort.Direction.DESC, "flashSaleWeight");
        Pageable pageable = PageRequest.of(0, limit, sort);
        Page<BookDTO> books = bookService.getBooksByType(null, null, true, pageable);
        return ResponseEntity.ok(books.getContent());
    }
    
    /**
     * 获取"猜你喜欢"的图书推荐
     * 如果提供了userId，则基于用户历史记录推荐
     * 否则返回随机推荐的图书
     */
    @GetMapping("/you-may-like")
    public ResponseEntity<List<BookDTO>> getYouMayLikeBooks(
            @RequestParam(required = false) Long userId,
            @RequestParam(required = false) Long categoryId,
            @RequestParam(defaultValue = "10") int limit) {
        
        // 调用服务层方法获取推荐图书
        List<BookDTO> recommendedBooks = bookService.getYouMayLikeBooks(userId, categoryId, limit);
        return ResponseEntity.ok(recommendedBooks);
    }
}